﻿Ext.lib.Panel = Ext.extend(Ext.Container, {

    baseCls: 'x-panel',

    isPanel: true,

    componentLayout: 'dock',

    renderTpl: ['<div class="{baseCls}-body<tpl if="bodyCls"> {bodyCls}</tpl>"<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>></div>'],

    initComponent: function () {
        this.addEvents(
            'bodyresize'
        );

        //给组件选择符对象加一个属性
        Ext.applyIf(this.renderSelectors, {
            body: '.' + this.baseCls + '-body'
        });

        Ext.lib.Panel.superclass.initComponent.call(this);
    },

    //将子组件信息放到内部集合中
    initItems: function () {

        //调用父类同名方法，将非停靠子组件放到内部集合中
        Ext.lib.Panel.superclass.initItems.call(this);

        //创建新集合，专门存放停靠子组件
        var items = this.dockedItems;
        this.dockedItems = new Ext.util.MixedCollection(false, this.getComponentId);
        if (items) {
            this.addDocked(items);//将停靠子组件添加到新集合中
        }
    },

    //获取指定的停靠子组件
    getDockedComponent: function (comp) {
        if (Ext.isObject(comp)) {
            comp = comp.getItemId();
        }
        return this.dockedItems.get(comp);
    },

    //获取指定的子组件（包括停靠子组件）
    getComponent: function (comp) {

        //调用父类同名方法，获取指定的非停靠子组件
        var component = Ext.lib.Panel.superclass.getComponent.call(this, comp);

        //如果找不到指定的组件，则获取指定的停靠子组件
        if (component == undefined) {
            component = this.getDockedComponent(comp);
        }
        return component;
    },

    //整理renderTpl中外层DIV的style
    initBodyStyles: function () {
        var bodyStyle = Ext.isString(this.bodyStyle) ? this.bodyStyle.split(';') : [],
            Element = Ext.Element;

        if (this.bodyPadding != undefined) {
            bodyStyle.push('padding: ' + Element.unitizeBox((this.bodyPadding === true) ? 5 : this.bodyPadding));
        }
        if (this.bodyMargin != undefined) {
            bodyStyle.push('margin: ' + Element.unitizeBox((this.bodyMargin === true) ? 5 : this.bodyMargin));
        }
        if (this.bodyBorder != undefined) {
            bodyStyle.push('border-width: ' + Element.unitizeBox((this.bodyBorder === true) ? 1 : this.bodyBorder));
        }
        delete this.bodyStyle;
        return bodyStyle.length ? bodyStyle.join(';') : undefined;
    },

    //初始化renderTpl的渲染数据
    initRenderData: function () {

        //先调用父类的同名方法初始化数据，然后再此基础上添加样式信息
        return Ext.applyIf(Ext.lib.Panel.superclass.initRenderData.call(this), {
            bodyStyle: this.initBodyStyles(),//renderTpl中外层DIV的style
            bodyCls: this.bodyCls//renderTpl中外层DIV的样式类
        });
    },

    //将停靠子组件添加到停靠集合指定位置
    addDocked: function (items, pos) {

        //创建子组件实例，以数组形式返回
        items = this.prepareItems(items);

        var item, i, ln;
        for (i = 0, ln = items.length; i < ln; i++) {
            item = items[i];
            item.dock = item.dock || 'top';
            if (pos !== undefined) {
                this.dockedItems.insert(pos + i, item);//将停靠子组件插入集合指定位置
            }
            else {
                this.dockedItems.add(item);//将停靠子组件加入集合末尾
            }
            item.onAdded(this, i);
            this.onDockedAdd(item);
        }
        if (this.rendered) {
            this.doComponentLayout();//重新布局
        }
    },


    onDockedAdd: Ext.emptyFn,
    onDockedRemove: Ext.emptyFn,

    //添加浮动子组件
    insertDocked: function (pos, items) {
        this.addDocked(items, pos);
    },

    //移除停靠子组件
    removeDocked: function (item, autoDestroy) {
        if (!this.dockedItems.contains(item)) {
            return item;
        }

        var layout = this.componentLayout,
            hasLayout = layout && this.rendered;

        if (hasLayout) {
            layout.onRemove(item);//布局类中移除停靠子组件的处理
        }

        this.dockedItems.remove(item);//将子组件从停靠集合中移除
        item.onRemoved();
        this.onDockedRemove(item);

        if (autoDestroy === true || (autoDestroy !== false && this.autoDestroy)) {
            item.destroy();//销毁停靠子组件
        }

        if (hasLayout && !autoDestroy) {
            layout.afterRemove(item);
        }
        this.doComponentLayout();//重新布局

        return item;
    },

    //获取停靠子组件数组
    getDockedItems: function () {
        if (this.dockedItems && this.dockedItems.items.length) {
            return this.dockedItems.items.slice();
        }
        return [];
    },

    //获取renderTpl模板中最外层DOM，this.body是renderTpl选择符之一，代表模板最外层
    getTargetEl: function () {
        return this.body;
    },

    //获取所有下级组件（包括子组件的子组件）
    getRefItems: function (deep) {

        //调用父类的同名方法获取所有下级组件（非停靠）
        var refItems = Ext.lib.Panel.superclass.getRefItems.call(this, deep),

            //获取停靠子组件
            dockedItems = this.getDockedItems(),
            ln = dockedItems.length,
            i = 0,
            item;

        //合并所有子组件
        refItems = refItems.concat(dockedItems);

        //往更深一级遍历，获取下一级子组件
        if (deep) {
            for (; i < ln; i++) {
                item = dockedItems[i];
                if (item.getRefItems) {
                    refItems = refItems.concat(item.getRefItems(true));
                }
            }
        }

        return refItems;
    },

    //组件销毁前的准备工作
    beforeDestroy: function () {
        var docked = this.dockedItems,
            c;

        if (docked) {
            while ((c = docked.first())) {
                this.removeDocked(c, true);//移除停靠子组件
            }
        }

        //调用父类同名方法，移除非停靠子组件
        Ext.lib.Panel.superclass.beforeDestroy.call(this);
    }
});

